package com.tanhua.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.app.exception.ErrorResult;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.config.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.pojo.Question;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    //今日佳人
    public TodayBest todayBest() {
        //1.获取当前登录用户id
        Long userId = UserHolder.getUserId();
        //2.掉用api查询
        RecommendUser recommendUser = recommendUserApi.finndWithMaxScore(userId);
        //3.将查询结果转换为vo对象
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest todayBest = TodayBest.init(userInfo,recommendUser);
        //4.返回结果
        return todayBest;
    }

    //首页推荐
    public PageResult recommendation(RecommendUserDto recommendUserDto) {
        //获取登录用户id
        Long userId = UserHolder.getUserId();
        //查询推荐好友得到list集合
        List<RecommendUser> recommendUserList = recommendUserApi.findByUserId(userId);
        //判断列表是否为空
        if (recommendUserList==null || recommendUserList.isEmpty()) {
            return new PageResult(recommendUserDto.getPage(),recommendUserDto.getPagesize(),0,null);
        }
        //获取推荐好友的ids
        List<Long> ids = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        //根据推荐好友id和查询条件分页查询用户详情userInfo
        Page<UserInfo> pages = userInfoApi.findByDto(ids,recommendUserDto);
        List<UserInfo> userInfoList = pages.getRecords();
        Map<Long, UserInfo> map = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));

        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (userInfo != null) {
                TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
                list.add(todayBest);
            }
        }
        return new PageResult(recommendUserDto.getPage(),recommendUserDto.getPagesize(), (int) pages.getTotal(),list);
    }

    //查询感兴趣的人的信息
    public TodayBest personalInfo(Long userId) {
        //根据userId查询感兴趣的人的详细信息
        UserInfo userInfo = userInfoApi.findById(userId);
        //根据userId和登录人id查询推荐得分
        RecommendUser recommendUser = recommendUserApi.findById(userId,UserHolder.getUserId());
        //构造访客数据，调用API保存
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);
        //封装到TodayBest
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }

    //查询陌生人问题
    public String strangerQuestions(Long userId) {
        //根据userId查询question表查询问题
        Question question = questionApi.findByUserId(userId);
        return question==null ? "你喜欢java吗?": question.getTxt();
    }

    //回复陌生人问题
    public void replyStrangerQuestions(Long userId, String reply) {
        UserInfo userInfo = userInfoApi.findById(UserHolder.getUserId());
        //封装消息格式
        Map map = new HashMap();
        map.put("userId",UserHolder.getUserId());
        map.put("huanXinId", Constants.HX_USER_PREFIX+UserHolder.getUserId());
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);

        String json = JSON.toJSONString(map);

        huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX+userId,json);
    }

    @Value("${tanhua.default.recommend.users}")
    private List<Long>  userIds;

    //查询推荐用户
    public List<TodayBest> cards(Long userId) {
        //1.调用api查询推荐用户 排除喜欢和不喜欢的用户 数量限制为10
        List<RecommendUser> list = recommendUserApi.cards(userId,10);
        //2.判断数据是否存在 如果不存在 构造默认数据
        if (CollUtil.isEmpty(list)){
            list = new ArrayList<>();
            for (Long id : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(id);
                recommendUser.setToUserId(userId);
                recommendUser.setScore(RandomUtil.randomDouble(60,90));
                list.add(recommendUser);
            }
        }
        //3.查询用户详情
        List<Long> ids = list.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfoList = userInfoApi.findByIds(ids);
        Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        //4.构造vo
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser recommendUser : list) {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            if (userInfo!=null){
                TodayBest vo = TodayBest.init(userInfo,recommendUser);
                vos.add(vo);
            }
        }
        return vos;
    }

    //喜欢
    public void love(Long userId, Long loveUserId) {
        //保存数据到userlike表中 并返回是否保存成功
        Boolean save = userLikeApi.saveOrUpdate(userId,loveUserId,true);
        if (!save){
            throw new RuntimeException("保存喜欢数据失败");
        }
        //将喜欢数据添加到redis中
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+userId,loveUserId.toString());
        //删除redis中的不喜欢数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+userId,loveUserId.toString());

        //判断是否是双向喜欢 如果是则添加好友
        Boolean member = redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY + userId, loveUserId.toString());
        if (member){
            friendApi.save(userId,loveUserId);
        }
    }

    //不喜欢
    public void unLove(Long userId, Long loveUserId) {
        //保存数据到userlike表中 并返回是否保存成功
        Boolean save = userLikeApi.saveOrUpdate(userId,loveUserId,false);
        if (!save){
            throw new RuntimeException("保存不喜欢数据失败");
        }
        //将不喜欢数据添加到redis中
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+userId,loveUserId.toString());
        //删除redis中的喜欢数据
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+userId,loveUserId.toString());

        //判断是否是双向喜不欢 如果是则删除好友关系
        Boolean member = redisTemplate.opsForSet().isMember(Constants.USER_NOT_LIKE_KEY + userId, loveUserId.toString());
        if (member){
            //删除MongoDB表中的数据
            friendApi.remove(userId,loveUserId);
            //删除环信中的数据
            huanXinTemplate.deleteContact(Constants.HX_USER_PREFIX+userId,Constants.HX_USER_PREFIX+loveUserId);
        }
    }

    //搜附近
    public List<NearUserVo> search(Long userId, String gender, String distance) {
        //搜索当前用户附近的人
        List<Long> ids = userLocationApi.searchNearUser(userId,Double.parseDouble(distance));
        //判断是否为空
        if (CollUtil.isEmpty(ids)){
            return null;
        }
        //根据附近的人的id和性别查询用户信息
        List<UserInfo> userInfoList = userInfoApi.findByIdsGender(ids,gender);
        //封装到vo中
        List<NearUserVo> vos = new ArrayList<>();
        for (UserInfo userInfo : userInfoList) {
            //排除自己
            if (userInfo.getId() == userId){
                continue;
            }

            NearUserVo vo = NearUserVo.init(userInfo);
            vos.add(vo);
        }

        return vos;
    }

    //查看佳人详情
    public TodayBest todayBestInfo(Long userId) {
        //1、根据用户id查询，用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //2、根据操作人id和查看的用户id，查询两者的推荐数据
        RecommendUser user = recommendUserApi.findById(userId, UserHolder.getUserId());

        //构造访客数据，调用API保存
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(user.getScore());
        visitorsApi.save(visitors);

        //3、构造返回值
        return TodayBest.init(userInfo, user);
    }
}
